import tkinter as tk
from tkinter import scrolledtext, ttk, filedialog
import threading
import queue
import os
import re
from datetime import datetime
import configparser

class FileFinder:
    def __init__(self, root):
        self.root = root
        self.root.title("文件查找工具 著作:MrCui")
        self.root.geometry("580x650")
        self.root.geometry("+%d+%d" % (root.winfo_screenwidth() // 2 - 290, root.winfo_screenheight() // 2 - 325))

        # 初始化样式
        self.style = ttk.Style(root)
        self.style.theme_use('default')

        # 日志配置
        self.log_dir = r"C:\FilesLogs"
        self.log_file = os.path.join(self.log_dir, "app.log")
        self.config_file = os.path.join(self.log_dir, "config.ini")
        self.log_queue = queue.Queue()
        self.current_row = 0

        # 任务控制
        self.search_running = False
        self.search_thread = None

        # 初始化日志系统
        self.init_log_system()
        self.create_widgets()
        # 加载配置，移到 create_widgets 之后
        self.load_config()
        self.root.after(100, self.process_log_queue)

    def init_log_system(self):
        """初始化日志系统"""
        try:
            # 创建日志目录（如果不存在）
            os.makedirs(self.log_dir, exist_ok=True)

            # 创建/清空日志文件（如果不存在）
            if not os.path.exists(self.log_file):
                with open(self.log_file, 'w') as f:
                    f.write("")
                self.insert_log(f"已创建日志文件：{self.log_file}")

            self.insert_log("========== 应用程序启动 著作:MrCui ==========")
        except Exception as e:
            self.log_queue.put(f"日志系统初始化失败：{str(e)}")

    def write_to_logfile(self, message):
        """写入日志文件"""
        try:
            timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            with open(self.log_file, 'a', encoding='utf-8') as f:
                f.write(f"[{timestamp}] {message}\n")
        except Exception as e:
            self.log_queue.put(f"写入日志文件失败：{str(e)}")

    def create_widgets(self):
        """创建界面组件"""
        # 标题
        title_label = tk.Label(self.root,
                               text="文件查找工具",
                               font=("楷体", 12, "bold"),
                               fg="red")
        title_label.pack(side=tk.TOP, fill=tk.X, pady=(0, 0))

        font_style = ("楷体", 12)
        main_frame = tk.Frame(self.root, padx=20, pady=20)
        main_frame.pack(fill=tk.BOTH, expand=True)

        # 日志路径显示
        log_path_frame = tk.LabelFrame(main_frame,
                                       text="日志存储路径",
                                       font=font_style,
                                       padx=10,
                                       pady=10)
        log_path_frame.pack(side=tk.TOP, fill=tk.X, pady=(0, 10))

        self.log_path_var = tk.StringVar(value=self.log_file)
        tk.Label(log_path_frame, text="日志文件:", font=font_style).grid(row=0, column=0, sticky=tk.W, pady=5)
        log_entry = tk.Entry(log_path_frame,
                             textvariable=self.log_path_var,
                             width=50,
                             font=font_style,
                             state='readonly')
        log_entry.grid(row=0, column=1, padx=10, pady=5, sticky=tk.E + tk.W)

        # 扫描目录输入区
        scan_frame = tk.LabelFrame(main_frame,
                                   text="需要扫描的目录",
                                   font=font_style,
                                   padx=10,
                                   pady=10)
        scan_frame.pack(side=tk.TOP, fill=tk.X, pady=(0, 10))

        self.scan_path_var = tk.StringVar()
        tk.Label(scan_frame, text="扫描路径:", font=font_style).grid(row=0, column=0, sticky=tk.W, pady=5)
        scan_entry = tk.Entry(scan_frame,
                              textvariable=self.scan_path_var,
                              width=40,
                              font=font_style,
                              state='readonly')
        scan_entry.grid(row=0, column=1, padx=10, pady=5, sticky=tk.E + tk.W)
        scan_button = tk.Button(scan_frame,
                                text="选择路径",
                                command=self.select_scan_path,
                                font=font_style)
        scan_button.grid(row=0, column=2, padx=10, pady=5)

        # 搜索目录输入区
        search_frame = tk.LabelFrame(main_frame,
                                     text="需要搜索的目录",
                                     font=font_style,
                                     padx=10,
                                     pady=10)
        search_frame.pack(side=tk.TOP, fill=tk.X, pady=(0, 10))

        self.search_path_var = tk.StringVar()
        tk.Label(search_frame, text="搜索路径:", font=font_style).grid(row=0, column=0, sticky=tk.W, pady=5)
        search_entry = tk.Entry(search_frame,
                                textvariable=self.search_path_var,
                                width=40,
                                font=font_style,
                                state='readonly')
        search_entry.grid(row=0, column=1, padx=10, pady=5, sticky=tk.E + tk.W)
        search_button = tk.Button(search_frame,
                                  text="选择路径",
                                  command=self.select_search_path,
                                  font=font_style)
        search_button.grid(row=0, column=2, padx=10, pady=5)

        # 控制按钮区
        button_frame = tk.Frame(main_frame)
        button_frame.pack(side=tk.TOP, fill=tk.X, pady=(0, 10))

        self.start_button = tk.Button(button_frame,
                                      text="开始查找",
                                      command=self.start_search,
                                      font=font_style,
                                      width=10)
        self.start_button.pack(side=tk.LEFT, padx=10)

        self.stop_button = tk.Button(button_frame,
                                     text="停止查找",
                                     command=self.stop_search,
                                     font=font_style,
                                     width=10,
                                     state=tk.DISABLED)
        self.stop_button.pack(side=tk.LEFT, padx=10)

        # 日志显示区
        log_frame = tk.LabelFrame(main_frame,
                                  text="操作日志",
                                  font=font_style,
                                  padx=10,
                                  pady=10)
        log_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True)

        self.text_box = scrolledtext.ScrolledText(log_frame, width=80, height=20, font=font_style)
        self.text_box.pack(fill=tk.BOTH, expand=True)

        self.row_label = tk.Label(main_frame, text="当前执行行数: 0", font=font_style)
        self.row_label.pack(side=tk.BOTTOM, pady=5)

    def select_scan_path(self):
        """选择扫描路径"""
        path = filedialog.askdirectory()
        if path:
            self.scan_path_var.set(path)

    def select_search_path(self):
        """选择搜索路径"""
        path = filedialog.askdirectory()
        if path:
            self.search_path_var.set(path)

    def toggle_controls(self, state):
        """切换控件状态"""
        controls = [
            self.start_button
        ]

        for control in controls:
            control["state"] = state

        self.stop_button["state"] = tk.NORMAL if state == tk.DISABLED else tk.DISABLED

    def insert_log(self, message, error=False):
        """记录日志"""
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        log_message = f"[{timestamp}] {message}"

        # 写入队列和文件
        self.log_queue.put(log_message)
        self.write_to_logfile(log_message)

    def process_log_queue(self):
        """处理日志队列"""
        try:
            while True:
                message = self.log_queue.get_nowait()
                self.text_box.insert(tk.END, f"{message}\n")
                self.text_box.see(tk.END)
                self.current_row += 1
                self.row_label.config(text=f"当前执行行数: {self.current_row}")
        except queue.Empty:
            pass
        self.root.after(100, self.process_log_queue)

    def search_files(self):
        """执行文件查找操作"""
        try:
            scan_path = self.scan_path_var.get()
            search_path = self.search_path_var.get()

            # 参数验证
            if not all([scan_path, search_path]):
                self.insert_log("错误：请选择扫描路径和搜索路径", error=True)
                return

            if not os.path.exists(scan_path):
                self.insert_log(f"错误：扫描路径不存在 - {scan_path}", error=True)
                return

            if not os.path.exists(search_path):
                self.insert_log(f"错误：搜索路径不存在 - {search_path}", error=True)
                return

            # 执行查找
            self.insert_log("开始文件扫描...")
            file_names = []
            for root, dirs, files in os.walk(scan_path):
                if not self.search_running:
                    break
                for file in files:
                    file_names.append(file)
                    self.insert_log(f"扫描到文件: {file}")

            self.insert_log("开始查找重复文件...")
            found_count = 0
            for file in file_names:
                if not self.search_running:
                    break
                for search_root, search_dirs, search_files in os.walk(search_path):
                    if not self.search_running:
                        break
                    try:
                        if file in search_files:
                            file_path = os.path.join(search_root, file)
                            self.insert_log(f"找到文件: {file_path}")
                            found_count += 1
                    except Exception as e:
                        self.insert_log(f"查找文件 {file} 时出现错误: {str(e)}", error=True)

            if found_count == 0:
                self.insert_log("未找到重复文件。")
            self.insert_log("文件查找操作完成")
            self.stop_search()

        except Exception as e:
            self.insert_log(f"发生未预期的错误：{str(e)}", error=True)

    def start_search(self):
        """启动文件查找任务"""
        # 禁用控件
        self.toggle_controls(tk.DISABLED)
        self.search_running = True

        # 启动搜索线程
        def search_loop():
            self.search_files()

        self.search_thread = threading.Thread(target=search_loop, daemon=True)
        self.search_thread.start()
        self.insert_log("文件查找任务已启动")

    def stop_search(self):
        """停止文件查找任务"""
        self.search_running = False
        self.toggle_controls(tk.NORMAL)
        self.insert_log("文件查找任务已停止")

    def load_config(self):
        """加载配置文件"""
        if os.path.exists(self.config_file):
            config = configparser.ConfigParser()
            config.read(self.config_file)
            if 'Settings' in config:
                settings = config['Settings']
                self.scan_path_var.set(settings.get('scan_path', ''))
                self.search_path_var.set(settings.get('search_path', ''))

    def save_config(self):
        """保存配置文件"""
        config = configparser.ConfigParser()
        config['Settings'] = {
            'scan_path': self.scan_path_var.get(),
            'search_path': self.search_path_var.get()
        }
        with open(self.config_file, 'w') as configfile:
            config.write(configfile)


if __name__ == "__main__":
    root = tk.Tk()
    app = FileFinder(root)
    root.mainloop()
